function reactive (target) {
  return new Proxy(target, {
    get (target, key, receiver) {
      track(target, key) // 依赖追踪
      return Reflect.get(target, key)
    },

    set (target, key, value, receiver) {
      const flag = Reflect.set(target, key, value)
      trigger(target, key) // 触发
      return flag
    }
  })
}

const targetMap = new WeakMap()
let activeEffect

function cleanup (effectFn) {
  for (let i = 0; i < effectFn.deps.length; i++) {
    const deps = effectFn.deps[i]
    deps.delete(effectFn)
  }
  effectFn.deps.length = 0
}

function effect (fn) {
  const effectFn = () => {
    cleanup(effectFn)
    activeEffect = effectFn
    fn()
  }

  effectFn.deps = []
  effectFn()
}

function track (target, key) {
  if (!activeEffect) return

  let depsMap = targetMap.get(target)
  if (!depsMap) {
    targetMap.set(target, (depsMap = new Map()))
  }

  let deps = depsMap.get(key)
  if (!deps) {
    depsMap.set(key, (deps = new Set()))
  }

  deps.add(activeEffect)

  activeEffect.deps.push(deps) // 存储当前函数所有副作用set集合
}

function trigger (target, key) {
  const depsMap = targetMap.get(target)

  if (!depsMap) return

  const effects = depsMap.get(key)

  const effectsToRun = new Set(effects)
  effectsToRun.forEach(effectFn => effectFn())
  // effects && effects.forEach(effectFn => effectFn())
}

const obj = reactive({
  a: 1,
  b: 2,
  flag: true
})

effect(function effect_1() {
  console.log(obj.flag ? obj.a : obj.b)
})

obj.flag = false
obj.b = 3


